/**
 * Copyright (c) Software Institute of PKU
 * All rights reserved. 
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 */
package edu.pku.sei.modeler.editparts;

import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gef.editpolicies.DirectEditPolicy;
import org.eclipse.gef.editpolicies.LayoutEditPolicy;
import org.eclipse.gef.editpolicies.ResizableEditPolicy;
import org.eclipse.gef.handles.MoveHandle;
import org.eclipse.gef.handles.NonResizableHandleKit;
import org.eclipse.gef.handles.ResizableHandleKit;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gef.tools.DragEditPartsTracker;

import edu.pku.sei.modeler.commands.CreateNodeCommand;
import edu.pku.sei.modeler.edit.policies.DiagramLayoutEditPolicy;
import edu.pku.sei.modeler.editpolicies.SequenceNodeEditPolicy;
import edu.pku.sei.modeler.figures.CombinedFragmentFigure;
import edu.pku.sei.modeler.model.structure.MetaDiagram;
import edu.pku.sei.modeler.model.structure.MetaLink;
import edu.pku.sei.modeler.model.structure.MetaNode;
import edu.pku.sei.modeler.model.structure.MetaShapeElement;
import edu.pku.sei.modeler.model.uml.Dependencies.Dependency;
import edu.pku.sei.modeler.model.uml.Fragments.CombinedFragment;
import edu.pku.sei.modeler.model.uml.Kernel.Comment;
import edu.pku.sei.modeler.uml.commands.sequence.SequenceDiagramElementCreateCommandFactory;

/**
 * 
 * @generated
 *
 */
public class CombinedFragmentEditpart extends AbstractUMLNodeEditPart 
{
	public CombinedFragmentEditpart (MetaShapeElement model) {
		super(model);
	}
	/* (non-Javadoc)
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
	 */
	protected IFigure createFigure() {
//		this.getModelElement().setInteractionOperator(InteractionOperator.SEQ);
		return new CombinedFragmentFigure(this.getModelElement().getInteractionOperator().getValue());
	}

	protected DirectEditPolicy createDirectEditPolicy() {
		return null;
	}
	
	@Override
	protected IFigure getDirectEditFigure() {
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
	 */
	protected void createEditPolicies() {
		super.createEditPolicies();
		installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new SequenceNodeEditPolicy());
		installEditPolicy(EditPolicy.LAYOUT_ROLE, new DiagramLayoutEditPolicy(){

			protected Command getCreateCommand(CreateRequest request) {
				MetaNode node = (MetaNode) request.getNewObject();
				MetaNode hostNode = (MetaNode) this.getHost().getModel();
				Rectangle constraint = ((Rectangle) getConstraintFor(request));
				
				return SequenceDiagramElementCreateCommandFactory.INSTANCE.createCommand(node, hostNode, constraint);
			}
			
			protected Command getOrphanChildrenCommand(Request request) {
				return UnexecutableCommand.INSTANCE;
			}
			
			protected EditPolicy createChildEditPolicy(EditPart child) {
				
				ResizableEditPolicy policy = new ResizableEditPolicy() {
					@SuppressWarnings("unchecked")
					@Override
					protected List createSelectionHandles() {
						List list = new ArrayList();
						int directions = this.getResizeDirections();

						if (directions == 0)
							NonResizableHandleKit.addHandles((GraphicalEditPart) getHost(), list);
						else if (directions != -1) {
//							ResizableHandleKit.addMoveHandle((GraphicalEditPart) getHost(), list);
							list.add(new MoveHandle((GraphicalEditPart) getHost()) {
								@Override
								protected DragTracker createDragTracker() {
									DragEditPartsTracker tracker = new DragEditPartsTracker(getOwner()) {
										protected Command getCommand() {
											CompoundCommand command = new CompoundCommand();
											command.setDebugLabel("Drag Object Tracker");
											Iterator iter = getOperationSet().iterator();
											Request request = getTargetRequest();
											request.setType(REQ_MOVE);
											while (iter.hasNext()) {
												EditPart editPart = (EditPart)iter.next();
												if (editPart instanceof CombinedFragmentEditpart)
													command.add(editPart.getCommand(request));
											}
											return command;
										}
									};
									tracker.setDefaultCursor(getCursor());
									return tracker;
								}
							});
							if ((directions & PositionConstants.EAST) != 0)
								ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.EAST);
//							else
//								NonResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.EAST);
							if ((directions & PositionConstants.SOUTH_EAST) == PositionConstants.SOUTH_EAST)
								ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.SOUTH_EAST);
//							else
//								NonResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.SOUTH_EAST);
							if ((directions & PositionConstants.SOUTH) != 0)
								ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.SOUTH);
//							else
//								NonResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.SOUTH);
							if ((directions & PositionConstants.SOUTH_WEST) == PositionConstants.SOUTH_WEST)
								ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.SOUTH_WEST);
//							else
//								NonResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.SOUTH_WEST);
							if ((directions & PositionConstants.WEST) != 0)
								ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.WEST);
//							else
//								NonResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.WEST);
							if ((directions & PositionConstants.NORTH_WEST) == PositionConstants.NORTH_WEST)
								ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.NORTH_WEST);
//							else
//								NonResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.NORTH_WEST);
							if ((directions & PositionConstants.NORTH) != 0)
								ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.NORTH);
//							else
//								NonResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.NORTH);
							if ((directions & PositionConstants.NORTH_EAST) == PositionConstants.NORTH_EAST)
								ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.NORTH_EAST);
//							else
//								NonResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.NORTH_EAST);
						} else
							ResizableHandleKit.addHandles((GraphicalEditPart) getHost(), list);

						return list;
					}

				};
				if (child instanceof CombinedFragmentEditpart) {
					policy.setResizeDirections(PositionConstants.EAST
							+ PositionConstants.SOUTH_EAST 
							+ PositionConstants.SOUTH 
							+ PositionConstants.SOUTH_WEST 
							+ PositionConstants.WEST
							+ PositionConstants.NORTH_WEST
							+ PositionConstants.NORTH
							+ PositionConstants.NORTH_EAST);
				}
				return policy;
			}
		});
	}

	protected void handlePropertyChanged(PropertyChangeEvent event) {
		refreshVisuals();
		super.handlePropertyChanged(event);
	}
	
	public DragTracker getDragTracker(Request request) {
		return new DragEditPartsTracker(this) {
			@Override
			protected void updateTargetRequest() {
				super.updateTargetRequest();
			}
			
			protected Command getCommand() {
				CompoundCommand command = new CompoundCommand();
				Iterator iter = getOperationSet().iterator();
				Request request = getTargetRequest();
				request.setType(REQ_MOVE);
				while (iter.hasNext()) {
					EditPart editPart = (EditPart)iter.next();
					command.add(editPart.getCommand(request));
				}
				return command;
			}
		};
	}
	
	private CombinedFragment getModelElement() {
		return (CombinedFragment)((MetaNode)getModel()).getModelElement();
	}
	
	protected void refreshVisuals() {
		this.getFigure().setOpaque(false);
//		CombinedFragment modelEle = (CombinedFragment)getNode().getModelElement();
		CombinedFragmentFigure figure = (CombinedFragmentFigure)getFigure();
		figure.setLabel(this.getModelElement().getInteractionOperator().toString());
		super.refreshVisuals();
		
		
	}
	
	public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection) {
		return null;
	}
	
	public ConnectionAnchor getSourceConnectionAnchor(Request request) {
		return null;
	}

	public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart connection) {
		if (connection == null || connection.getSource() == null) return null;
		if (connection.getSource() != null &&
				((MetaNode)connection.getSource().getModel()).getModelElement() instanceof Comment) {
			return super.getTargetConnectionAnchor(connection);
		}
		return null;
	}
	
	public ConnectionAnchor getTargetConnectionAnchor(Request request) {
		return null;
	}
}
